package com.gitee.beiding.template_execel;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class FunctionUtils {

    static String handleCacheableFunction(String s) {

        int start = s.indexOf('{') + 1;
        int end = s.lastIndexOf('}');

        String s1 = s.substring(0, start);

        String s2 = s.substring(start, end);

        String s3 = s.substring(end);

        //加入缓存
        s = s1 + "\nvar r = _cacheGet(arguments);\n" +
                "    if (r != null) {\n" +
                "        return r;\n" +
                "    }"
                + handleCacheableReturn(s2)
                + s3
        ;

        return s;
    }

    private static Pattern functionPattern = Pattern.compile("[^a-zA-Z0-9_](function)[^a-zA-Z0-9_]");
    private static Pattern returnPattern = Pattern.compile("[^a-zA-Z0-9_](return)[^a-zA-Z0-9_]");

    private static String handleCacheableReturn(String s) {

        s = "\n" + s + "\n";

        StringUtils.StringRecover recover = StringUtils.extract(s);

        s = recover.getResult();

        Matcher matcher = functionPattern.matcher(s);

        StringBuilder builder = new StringBuilder();

        Map<String, String> map = new HashMap<>();

        int e = 0;

        int id = 0;

        //找到所用的函数声明
        while (matcher.find()) {

            int end = matcher.end(1);

            StringUtils.SubStringResult subStringResult = StringUtils.pairingSubString(s, end, '{', '}');

            //找到一对函数声明
            if (subStringResult != null) {
                builder.append(s, e, matcher.start(1));
                e = subStringResult.getEnd();
                String fn = "__FUNCTION_" + id++ + "{}";
                builder.append(fn);
                map.put(fn, s.substring(matcher.start(), subStringResult.getEnd()));
            }

        }

        if (e < s.length() - 1) {
            builder.append(s.substring(e));
        }

        s = builder.toString();

        builder.delete(0, builder.length());
        e = 0;
        matcher = returnPattern.matcher(s);
        while (matcher.find()) {
            int end = matcher.end(1);
            StringUtils.SubStringResult charSubString = StringUtils.findCharSubString(s, end, ';', '}', '\n');

            if (charSubString != null) {
                builder.append(s, e, charSubString.getStart());
                e = charSubString.getEnd();
                builder.append("  _cachePut(arguments,").append(charSubString.getSubString()).append(")");
            }

        }
        if (e < s.length() - 1) {
            builder.append(s.substring(e));
        }

        s = builder.toString();

        for (String key : map.keySet()) {
            s = s.replace(key, map.get(key));
        }

        return recover.recover(s);
    }


}
